﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace RecipeML.Test
{
	/// <summary>
	/// This test class should contain all the tests necessary to prove
	/// that this class is functioning well.
	/// </summary>
	[TestClass]
	public class MealTest
	{
		public MealTest()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get
			{
				return testContextInstance;
			}
			set
			{
				testContextInstance = value;
			}
		}

		#region Additional test attributes
		//
		// You can use the following additional attributes as you write your tests:
		//
		// Use ClassInitialize to run code before running the first test in the class
		// [ClassInitialize()]
		// public static void MyClassInitialize(TestContext testContext) { }
		//
		// Use ClassCleanup to run code after all tests in a class have run
		// [ClassCleanup()]
		// public static void MyClassCleanup() { }
		//
		// Use TestInitialize to run code before running each test 
		// [TestInitialize()]
		// public void MyTestInitialize() { }
		//
		// Use TestCleanup to run code after each test has run
		// [TestCleanup()]
		// public void MyTestCleanup() { }
		//
		#endregion

		#region General Tests

		[TestMethod]
		public void ShoppingList_WhenCalled_ReturnsEmptyListOfIngredients()
		{
			var m = new Meal();
			var s = m.GetShoppingList();
			Assert.IsTrue(s.Count == 0);
		}

		#endregion General Tests

		#region MealSunday

		[TestMethod]
		public void LoadFromFile_MealSunday_LoadsNumDiners()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			Assert.IsTrue(m.NumberOfDiners == 3);
		}

		[TestMethod]
		public void LoadFromFile_MealSunday_LoadsRecipes()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			Assert.IsTrue(m.Recipes.Count() == 3);
		}

		[TestMethod]
		public void LoadFromFile_MealSunday_LoadsName()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			Assert.IsTrue(m.Title == "Sunday Meal");
		}

		[TestMethod]
		public void ToString_MealSunday_ReturnsValidString()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			var s = m.ToString();
			Assert.IsFalse(string.IsNullOrEmpty(s));
		}

		[TestMethod]
		public void ShoppingList_MealSunday_ReturnsProperShoppingList()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			var s = m.GetShoppingList();
			Assert.IsTrue(s.Count == (6 + 8 + 8 + 1));  //distinct ingredients + 1 duplicate in each recipe
		}

		[TestMethod]
		public void ShoppingList_MealSunday_ReturnsProperDate()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			Assert.AreEqual(m.Date, DateTime.Parse("4/1/2012"));
		}

		[TestMethod]
		public void ToXML_MealSunday_ReturnValueCanBeLoaded()
		{
			var originalObj = new Meal();
			originalObj.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealSunday.xml");
			var newObj = new Meal();
			newObj.LoadFromString(originalObj.ToXML());
			Assert.AreEqual(originalObj.Title, newObj.Title);
			Assert.AreEqual(originalObj.NumberOfDiners, newObj.NumberOfDiners);
			Assert.AreEqual(originalObj.Recipes.Count(), newObj.Recipes.Count());
		}


		#endregion MealSunday

		#region MealMonday

		[TestMethod]
		public void LoadFromFile_MealMonday_LoadsNumDiners()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			Assert.IsTrue(m.NumberOfDiners == 10);
		}

		[TestMethod]
		public void LoadFromFile_MealMonday_LoadsRecipes()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			Assert.IsTrue(m.Recipes.Count() == 4);
		}

		[TestMethod]
		public void LoadFromFile_MealMonday_LoadsName()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			Assert.IsTrue(m.Title == "Monday Meal");
		}

		[TestMethod]
		public void ToString_MealMonday_ReturnsValidString()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			var s = m.ToString();
			Assert.IsFalse(string.IsNullOrEmpty(s));
		}

		[TestMethod]
		public void ShoppingList_MealMonday_ReturnsProperShoppingList()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			var s = m.GetShoppingList();
			Assert.IsTrue(s.Count == (6 + 8 + 8 + 1));  //distinct ingredients + 1 duplicate in each recipe
		}

		[TestMethod]
		public void ShoppingList_MealMonday_ReturnsProperDate()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			Assert.AreEqual(m.Date, DateTime.Parse("4/2/2012"));
		}

		[TestMethod]
		public void ToXML_MealMonday_ReturnValueCanBeLoaded()
		{
			var originalObj = new Meal();
			originalObj.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealMonday.xml");
			var newObj = new Meal();
			newObj.LoadFromString(originalObj.ToXML());
			Assert.AreEqual(originalObj.Title, newObj.Title);
			Assert.AreEqual(originalObj.NumberOfDiners, newObj.NumberOfDiners);
			Assert.AreEqual(originalObj.Recipes.Count(), newObj.Recipes.Count());
		}


		#endregion MealSunday
		
		#region MealTuesday

		[TestMethod]
		public void LoadFromFile_MealTuesday_LoadsNumDiners()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			Assert.IsTrue(m.NumberOfDiners == 0);
		}

		[TestMethod]
		public void LoadFromFile_MealTuesday_LoadsRecipes()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			Assert.IsTrue(m.Recipes.Count() == 0);
		}

		[TestMethod]
		public void LoadFromFile_MealTuesday_LoadsName()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			Assert.IsTrue(m.Title == "Tuesday Meal");
		}

		[TestMethod]
		public void ToString_MealTuesday_ReturnsValidString()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			var s = m.ToString();
			Assert.IsFalse(string.IsNullOrEmpty(s));
		}

		[TestMethod]
		public void ShoppingList_MealTuesday_ReturnsProperShoppingList()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			var s = m.GetShoppingList();
			Assert.IsTrue(s.Count == 0);  
		}

		[TestMethod]
		public void ShoppingList_MealTuesday_ReturnsProperDate()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			Assert.AreEqual(m.Date, DateTime.Parse("4/3/2012"));
		}

		[TestMethod]
		public void ToXML_MealTuesday_ReturnValueCanBeLoaded()
		{
			var originalObj = new Meal();
			originalObj.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealTuesday.xml");
			var newObj = new Meal();
			newObj.LoadFromString(originalObj.ToXML());
			Assert.AreEqual(originalObj.Title, newObj.Title);
			Assert.AreEqual(originalObj.NumberOfDiners, newObj.NumberOfDiners);
			Assert.AreEqual(originalObj.Recipes.Count(), newObj.Recipes.Count());
		}


		#endregion MealTuesday
		
		#region MealWednesday

		[TestMethod]
		public void LoadFromFile_MealWednesday_LoadsNumDiners()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealWednesday.xml");
			Assert.IsTrue(m.NumberOfDiners == 7);
		}

		[TestMethod]
		public void LoadFromFile_MealWednesday_LoadsRecipes()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealWednesday.xml");
			Assert.IsTrue(m.Recipes.Count() == 3);
		}

		[TestMethod]
		public void LoadFromFile_MealWednesday_LoadsName()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealWednesday.xml");
			Assert.IsTrue(m.Title == "Wednesday Meal");
		}


		[TestMethod]
		public void ShoppingList_MealWednesday_ReturnsProperShoppingList()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealWednesday.xml");
			var s = m.GetShoppingList();
			Assert.IsTrue(s.Count == 10); //only 10 distinct ingredients
		}

		[TestMethod]
		public void ShoppingList_MealWednesday_ReturnsProperShoppingListNumbers()
		{
			var m = new Meal();
			m.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealWednesday.xml");
			var s = m.GetShoppingList();
			Assert.IsTrue(s[0].amt == 3); //same ingredient one time in each of 3 recipes
		}


		[TestMethod]
		public void ToXML_MealWednesday_ReturnValueCanBeLoaded()
		{
			var originalObj = new Meal();
			originalObj.LoadFromFile(@"..\..\..\RecipeML.Test\TestData\MealWednesday.xml");
			var newObj = new Meal();
			newObj.LoadFromString(originalObj.ToXML());
			Assert.AreEqual(originalObj.Title, newObj.Title);
			Assert.AreEqual(originalObj.NumberOfDiners, newObj.NumberOfDiners);
			Assert.AreEqual(originalObj.Recipes.Count(), newObj.Recipes.Count());
		}

		#endregion MealTuesday
	}
}
